"""
交互式图像显示组件
处理图像显示、鼠标事件、标定点和区域可视化
"""

import os
from PyQt5.QtWidgets import QLabel, QScrollArea
from PyQt5.QtCore import Qt, pyqtSignal
from PyQt5.QtGui import QPixmap, QImage, QPainter, QPen, QColor, QFont


class ImageLabel(QLabel):
    clicked = pyqtSignal(int, int)
    area_selected = pyqtSignal(int, int, int, int)  # 区域选择信号 (x1, y1, x2, y2)
    area_completed = pyqtSignal(int, int, int, int)  # 区域完成信号，触发自动分析
    
    def __init__(self):
        super().__init__()
        self.setMinimumSize(400, 300)
        self.setStyleSheet("border: 1px solid black")
        self.setAlignment(Qt.AlignCenter)
        self.setScaledContents(False)
        self.original_pixmap = None
        
        # 区域选择相关
        self.area_selection_mode = False
        self.selecting_area = False
        self.start_point = None
        self.end_point = None
        self.selected_areas = []  # 存储已选择的区域
        self.area_statistics = []  # 存储区域统计信息
        self.extreme_points = []  # 存储每个区域的最高温和最低温点位置
        
        # 温度标记点
        self.temperature_marks = []  # 存储温度标记点 [{'x': int, 'y': int, 'temp': float, 'label': str}]
        
    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton and self.original_pixmap:
            # 获取点击位置相对于图像的坐标
            label_size = self.size()
            pixmap_size = self.original_pixmap.size()
            
            # 计算缩放比例
            scale_x = pixmap_size.width() / label_size.width()
            scale_y = pixmap_size.height() / label_size.height()
            scale = max(scale_x, scale_y)
            
            # 计算实际图像在label中的位置
            scaled_w = int(pixmap_size.width() / scale)
            scaled_h = int(pixmap_size.height() / scale)
            offset_x = (label_size.width() - scaled_w) // 2
            offset_y = (label_size.height() - scaled_h) // 2
            
            # 转换点击坐标
            click_x = event.x() - offset_x
            click_y = event.y() - offset_y
            
            if 0 <= click_x < scaled_w and 0 <= click_y < scaled_h:
                # 转换到原图坐标
                orig_x = int(click_x * scale)
                orig_y = int(click_y * scale)
                
                if self.area_selection_mode:
                    # 开始区域选择
                    self.start_point = (orig_x, orig_y)
                    self.selecting_area = True
                    self.end_point = None
                else:
                    # 普通点击模式
                    self.clicked.emit(orig_x, orig_y)
    
    def mouseMoveEvent(self, event):
        if self.selecting_area and self.start_point:
            # 更新区域选择的终点
            label_size = self.size()
            pixmap_size = self.original_pixmap.size()
            
            scale_x = pixmap_size.width() / label_size.width()
            scale_y = pixmap_size.height() / label_size.height()
            scale = max(scale_x, scale_y)
            
            scaled_w = int(pixmap_size.width() / scale)
            scaled_h = int(pixmap_size.height() / scale)
            offset_x = (label_size.width() - scaled_w) // 2
            offset_y = (label_size.height() - scaled_h) // 2
            
            click_x = event.x() - offset_x
            click_y = event.y() - offset_y
            
            if 0 <= click_x < scaled_w and 0 <= click_y < scaled_h:
                orig_x = int(click_x * scale)
                orig_y = int(click_y * scale)
                self.end_point = (orig_x, orig_y)
                self.update_area_display()
    
    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton and self.selecting_area and self.start_point and self.end_point:
            # 完成区域选择
            x1, y1 = self.start_point
            x2, y2 = self.end_point
            
            # 确保坐标正确排序
            x1, x2 = min(x1, x2), max(x1, x2)
            y1, y2 = min(y1, y2), max(y1, y2)
            
            self.selected_areas.append((x1, y1, x2, y2))
            self.area_selected.emit(x1, y1, x2, y2)
            self.area_completed.emit(x1, y1, x2, y2)  # 触发自动分析
            self.selecting_area = False
            self.start_point = None
            self.end_point = None
            self.update_area_display()
    
    def set_area_selection_mode(self, enabled):
        """设置区域选择模式"""
        self.area_selection_mode = enabled
        if not enabled:
            self.selecting_area = False
            self.start_point = None
            self.end_point = None
    
    def clear_selected_areas(self):
        """清空选中的区域"""
        self.selected_areas = []
        self.area_statistics = []
        self.extreme_points = []
        self.update_area_display()
    
    def add_temperature_mark(self, x, y, temperature, label=None):
        """添加温度标记点"""
        if label is None:
            label = f"{temperature:.1f}°C"
        
        mark = {
            'x': x,
            'y': y, 
            'temp': temperature,
            'label': label
        }
        self.temperature_marks.append(mark)
        self.update_area_display()
    
    def clear_temperature_marks(self):
        """清空温度标记点"""
        self.temperature_marks = []
        self.update_area_display()
        
    def update_area_statistics(self, area_stats, extreme_points):
        """更新区域统计信息和极值点"""
        self.area_statistics = area_stats
        self.extreme_points = extreme_points
        self.update_area_display()
                
    def set_image(self, pixmap):
        self.original_pixmap = pixmap
        self.update_display()
        
    def update_display(self):
        if self.original_pixmap:
            scaled_pixmap = self.original_pixmap.scaled(
                self.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation
            )
            self.setPixmap(scaled_pixmap)
            
    def update_area_display(self):
        """更新区域显示"""
        if not self.original_pixmap:
            return
            
        # 获取标定点信息（如果有的话）
        calibration_points = getattr(self, '_calibration_points', [])
        
        # 创建带所有标记的图像副本
        pixmap_with_marks = self.original_pixmap.copy()
        painter = QPainter(pixmap_with_marks)
        
        # 绘制标定点
        if calibration_points:
            pen = QPen(QColor(255, 0, 0), 3)
            painter.setPen(pen)
            font = QFont('Arial', 10, QFont.Bold)
            painter.setFont(font)
            
            for point in calibration_points:
                x, y = point['position']
                temp = point['temperature']
                
                painter.drawEllipse(x-8, y-8, 16, 16)
                
                label = f"{temp:.1f}°C"
                painter.setPen(QColor(0, 0, 0))  # 黑色描边
                painter.drawText(x+12, y-5, 60, 20, Qt.AlignLeft, label)
                painter.setPen(QColor(255, 255, 255))  # 白色字体
                painter.drawText(x+11, y-6, 60, 20, Qt.AlignLeft, label)
        
        # 绘制已完成的区域和统计信息
        for i, (x1, y1, x2, y2) in enumerate(self.selected_areas):
            # 确保每个区域都使用相同的画笔设置
            pen = QPen(QColor(0, 255, 0), 5)  # 更粗的绿色矩形
            painter.setPen(pen)
            painter.setBrush(Qt.NoBrush)  # 确保没有填充
            painter.drawRect(x1, y1, x2-x1, y2-y1)
            
            # 不显示区域编号，保持简洁
            
            # 显示平均温度在绿框左上角（如果有统计数据的话）
            if i < len(self.area_statistics):
                stats = self.area_statistics[i]
                
                # 设置平均温度显示的字体
                font = QFont('Arial', 11, QFont.Bold)
                painter.setFont(font)
                
                # 平均温度文本
                avg_temp_text = f"平均: {stats['avg_temp']:.1f}°C"
                
                # 计算文本尺寸
                metrics = painter.fontMetrics()
                text_width = metrics.width(avg_temp_text)
                text_height = metrics.height()
                
                # 位置：绿框左上角外侧
                temp_x = x1
                temp_y = y1 - 8
                
                # 调整位置避免超出边界
                if temp_y - text_height < 0:
                    temp_y = y1 + text_height + 8
                
                # 绘制白色半透明背景
                padding = 4
                bg_width = text_width + padding * 2
                bg_height = text_height + padding
                
                painter.setPen(QPen(QColor(200, 200, 200), 1))
                painter.setBrush(QColor(255, 255, 255, 220))
                painter.drawRect(temp_x, temp_y - text_height - padding//2, bg_width, bg_height)
                
                # 绘制平均温度文字
                painter.setBrush(Qt.NoBrush)
                painter.setPen(QColor(0, 0, 0))
                painter.drawText(temp_x + padding, temp_y - padding//2, avg_temp_text)
        
        # 绘制区域内的最高温和最低温点
        for i, extreme_point in enumerate(self.extreme_points):
            if 'max_point' in extreme_point and 'min_point' in extreme_point:
                # 绘制最高温点 - 红色圆圈
                max_x, max_y = extreme_point['max_point']
                painter.setPen(QPen(QColor(255, 0, 0), 4))
                painter.setBrush(QColor(255, 0, 0, 100))
                painter.drawEllipse(max_x-6, max_y-6, 12, 12)
                
                # 最高温点标签 - 白色字体
                painter.setPen(QColor(0, 0, 0))  # 黑色描边
                painter.drawText(max_x+9, max_y-7, f"最高{extreme_point['max_temp']:.1f}°C")
                painter.setPen(QColor(255, 255, 255))  # 白色字体
                painter.drawText(max_x+8, max_y-8, f"最高{extreme_point['max_temp']:.1f}°C")
                
                # 绘制最低温点 - 蓝色圆圈
                min_x, min_y = extreme_point['min_point']
                painter.setPen(QPen(QColor(0, 100, 255), 4))
                painter.setBrush(QColor(0, 100, 255, 100))
                painter.drawEllipse(min_x-6, min_y-6, 12, 12)
                
                # 最低温点标签 - 白色字体
                painter.setBrush(Qt.NoBrush)  # 重置填充
                painter.setPen(QColor(0, 0, 0))  # 黑色描边
                painter.drawText(min_x+9, min_y+16, f"最低{extreme_point['min_temp']:.1f}°C")
                painter.setPen(QColor(255, 255, 255))  # 白色字体
                painter.drawText(min_x+8, min_y+15, f"最低{extreme_point['min_temp']:.1f}°C")
                
                # 重置画笔状态，防止影响其他绘制
                painter.setPen(Qt.NoPen)
                painter.setBrush(Qt.NoBrush)
        
        # 绘制温度标记点 - 白色背景框样式
        for mark in self.temperature_marks:
            x, y = mark['x'], mark['y']
            label = mark['label']
            
            # 设置字体 - 与参考图像类似的字体设置
            font = QFont('Arial', 9, QFont.Bold)
            painter.setFont(font)
            
            # 分割多行文本
            lines = label.split('\n')
            
            # 计算最大文本宽度和总高度
            metrics = painter.fontMetrics()
            max_width = 0
            total_height = 0
            for line in lines:
                line_width = metrics.width(line)
                if line_width > max_width:
                    max_width = line_width
                total_height += metrics.height()
            
            # 设置背景框
            padding = 3
            box_width = max_width + padding * 2
            box_height = total_height + padding * 2
            
            # 调整位置避免超出图像边界，优先放在右上方
            box_x = x + 8
            box_y = y - box_height - 8
            
            # 检查边界并调整
            image_width = self.original_pixmap.width()
            image_height = self.original_pixmap.height()
            
            if box_x + box_width > image_width:
                box_x = x - box_width - 8
            if box_y < 0:
                box_y = y + 15
            if box_y + box_height > image_height:
                box_y = image_height - box_height - 5
            if box_x < 0:
                box_x = 5
            
            # 绘制白色背景框 - 与参考图像一致的半透明白色
            painter.setPen(QPen(QColor(200, 200, 200), 1))  # 浅灰色边框
            painter.setBrush(QColor(255, 255, 255, 200))  # 半透明白色背景
            painter.drawRect(box_x, box_y, box_width, box_height)
            
            # 绘制文本 - 黑色文字
            painter.setBrush(Qt.NoBrush)
            painter.setPen(QColor(0, 0, 0))  # 黑色文字
            
            # 绘制每一行文本
            current_y = box_y + padding + metrics.ascent()
            for line in lines:
                painter.drawText(box_x + padding, current_y, line)
                current_y += metrics.height()
            
            # 绘制指向标记点的小圆点 - 红色点
            painter.setPen(QPen(QColor(255, 0, 0), 2))
            painter.setBrush(QColor(255, 0, 0))
            painter.drawEllipse(x-2, y-2, 4, 4)
        
        # 重置画笔和画刷状态
        painter.setPen(Qt.NoPen)
        painter.setBrush(Qt.NoBrush)
        
        # 绘制正在选择的区域
        if self.selecting_area and self.start_point and self.end_point:
            pen = QPen(QColor(255, 255, 0), 5)  # 与绿色框相同的粗细
            pen.setStyle(Qt.DashLine)
            painter.setPen(pen)
            painter.setBrush(Qt.NoBrush)  # 确保没有填充
            
            x1, y1 = self.start_point
            x2, y2 = self.end_point
            painter.drawRect(min(x1, x2), min(y1, y2), abs(x2-x1), abs(y2-y1))
        
        painter.end()
        
        # 显示带标记的图像
        scaled_pixmap = pixmap_with_marks.scaled(
            self.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation
        )
        self.setPixmap(scaled_pixmap)
    
    def draw_calibration_points(self, calibration_points):
        """在图像上绘制标定点"""
        self._calibration_points = calibration_points
        self.update_area_display()